package com.practice.security;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.cert.CertificateException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class CertificatePractice {
	
	/**
	 * Public Key Cryptography Standards #12:<br>
	 * Personal Information Exchange Syntax Standard
	 */
	public static final String CRYPTOGRAPHY_PKCS12 = "PKCS12";
	
	/** X.509 certificate */
	public static final String CRYTOGRAPHY_X509 = "X.509";
	
	/** SHA1 with RSA */
	public static final String SIGNER_TYPE_SHA1_RSA = "SHA1withRSA";

	/** Unicode Transformation Format 8-bit */
	public static final String ENCODE_UTF8 = "UTF-8";
	
	
	public static void main(String[] args) {

		final String SIGNER_PRIVATE_KEY_PATH = "Certificate_with_Key.p12";
		
		final String SIGNER_PRIVATE_KEY_NEW_PATH = "Certificate_with_Key_New.p12";

		final String SIGNER_PRIVATE_KEY_PASSWORD = "mx73lkjx";
		
		try {
			KeyStore pkcs12KeyStore = loadKeyStore(SIGNER_PRIVATE_KEY_PATH, SIGNER_PRIVATE_KEY_PASSWORD);
			storeKeyStore(pkcs12KeyStore, SIGNER_PRIVATE_KEY_NEW_PATH, SIGNER_PRIVATE_KEY_PASSWORD);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	private static KeyStore loadKeyStore(String keyFilePath, String password) throws IOException {

		if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
			Security.addProvider(new BouncyCastleProvider());
		}

		/*
		 * Get key store instance.
		 */
		KeyStore pkcs12KeyStore;
		try {
			pkcs12KeyStore = KeyStore.getInstance(CRYPTOGRAPHY_PKCS12, BouncyCastleProvider.PROVIDER_NAME);
		} catch (NoSuchProviderException | KeyStoreException e) {
			throw new IOException("Create key store failed.", e);
		}

		/*
		 * Read key store from file.
		 */
		File signerPrivateKeyFile = new File(keyFilePath);
		try (InputStream signerPrivateKeyInputStream = new FileInputStream(signerPrivateKeyFile)) {
			pkcs12KeyStore.load(signerPrivateKeyInputStream, password.toCharArray());
		} catch (NoSuchAlgorithmException | CertificateException e) {
			throw new IOException("Load private key failed.", e);
		}

		return pkcs12KeyStore;
	}

	private static void storeKeyStore(KeyStore pkcs12KeyStore, String keyFilePath, String password) throws IOException {

		if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
			Security.addProvider(new BouncyCastleProvider());
		}

		/*
		 * Write key store to file.
		 */
		File signerPrivateKeyBackupFile = new File(keyFilePath);
		try (OutputStream output = new FileOutputStream(signerPrivateKeyBackupFile);) {
			pkcs12KeyStore.store(output, password.toCharArray());
		} catch (KeyStoreException | NoSuchAlgorithmException | CertificateException e) {
			throw new IOException("Store private key failed.", e);
		}

	}

}
